<?php

class Project_File {
	private $path;
	private $uri;
	private $fileName;
	private $name;
	private $extension;
	private $pathStartsWith;
	private $uriStartsWith;

	public static function createDirectory($dir, $isRecursive = true) {
		if (!is_dir($dir)) {
			$mask = umask(0);
			mkdir($dir, 0777, $isRecursive);
			umask($mask);
		}
	}

	public static function removeDirectory($dir, $isSelfDelete = true, $isOnlyFiles = false) {
		$dir = rtrim($dir, '/') . '/';
		if (is_dir($dir)) {
			$dirHandle = opendir($dir);
			while (false !== ($item = readdir($dirHandle))) {
				if ($item != '.' && $item != '..') {
					if (is_dir($dir . $item)) {
						if (!$isOnlyFiles) removeDirectory($dir . $item);
					} else {
						unlink($dir . $item);
					}
				}
			}
			if ($isSelfDelete) rmdir($dir);
			closedir($dirHandle);
		}
	}

	/**
	 * @return Project_File
	 */
	public static function getByName($dir, $name, $class = null) {
		if (is_dir($dir)) {
			if (is_null($class)) $class = __CLASS__;
			$dir = rtrim($dir, '/') . '/';

			foreach (array('.*', '*') as $try) {
				$search = glob($dir . $name . $try);
				if ($search) {
					return new $class($search[0], DOCUMENT_ROOT, '/');
				}
			}
		}
		return false;
	}

	public static function moveFile($from, $to) {
		if (is_file($from)) {
			self::deleteFile($to);
			return rename($from, $to);
		}

		return false;
	}

	public static function computeExtension($file) {
		$info = pathinfo($file);
		return isset($info['extension']) ? strtolower($info['extension']) : '';
	}

	public static function getSizeMeasure($size) {
		$result = array();

		if (0.5 < $size / (1024 * 1024)) {
			$result['value'] = $size / (1024 * 1024);
			$result['measure'] = 'МБ';
			$result['measure_en'] = 'MB';

		} elseif (0.5 < $size / 1024) {
			$result['value'] = $size / 1024;
			$result['measure'] = 'КБ';
			$result['measure_en'] = 'KB';

		} else {
			$result['value'] = $size;
			$result['measure'] = 'байт';
			$result['measure_en'] = 'bite';
		}

		$result['value'] = Project_String::formatNumber($result['value']);
		$result['string'] = $result['value'] . ' ' . $result['measure'];
		$result['string_en'] = $result['value'] . ' ' . $result['measure_en'];

		return $result;
	}

	public function __construct($path, $pathStartsWith = null, $uriStartsWith = null) {
		$this->setPathStartsWith($pathStartsWith);
		$this->setUriStartsWith($uriStartsWith);
		$this->setPath($path);
	}

	public function setPathStartsWith($path) {
		$this->pathStartsWith = $path;
	}

	public function getPathStartsWith() {
		return $this->pathStartsWith;
	}

	public function setUriStartsWith($uri) {
		$this->uriStartsWith = $uri;
	}

	public function getUriStartsWith() {
		return $this->uriStartsWith;
	}

	public function computeUri() {
		$this->uri =
			$this->getPathStartsWith() != ''
			? str_replace($this->getPathStartsWith(), $this->getUriStartsWith(), $this->getPath())
			: $this->getPath();
	}


	public function setPath($path) {
		$info = pathinfo($path);
		if (!isset($info['extension'])) $info['extension'] = '';

		$this->path = $path;
		$this->fileName = $info['basename'];
		$this->name = substr($info['basename'], 0, strlen($info['basename']) - strlen($info['extension']) - 1);
		$this->extension = $info['extension'];
		$this->computeUri();
	}

	public function delete() {
		self::deleteFile($this->getPath());
	}

	public static function deleteFile($filepath) {
		return is_file($filepath) ? unlink($filepath) : false;
	}

	public function getPath() {
		return $this->path;
	}

	public function getUri() {
		return $this->uri;
	}

	public function getFileName() {
		return $this->fileName;
	}

	public function getName() {
		return $this->name;
	}

	public function getExtension() {
		return $this->extension;
	}

	public function getSize() {
		return filesize($this->getPath());
	}

	public function getXml(array $attributes = array(), $xml = null, $nodeName = 'file') {
		$values = array(
			'uri' => $this->getUri(),
			'path' => $this->getPath(),
			'filename' => $this->getFileName(),
			'name' => $this->getName(),
			'extension' => $this->getExtension()
		);

		$result  = '<' . $nodeName;
		foreach (array_merge($values, $attributes) as $name => $value) {
			if ('' != $value) {
				$result .= ' ' . $name . '="' . $value . '"';
			}
		}
		$result .= '>';

		$size = self::getSizeMeasure($this->getSize());
		$result .= '<size xml:lang="ru" value="' . $size['value'] . '" measure="' . $size['measure'] . '"><![CDATA[' . $size['string'] . ']]></size>';
		$result .= '<size xml:lang="en" value="' . $size['value'] . '" measure="' . $size['measure_en'] . '"><![CDATA[' . $size['string_en'] . ']]></size>';

		$result .= $xml;
		$result .= '</' . $nodeName . '>';
		return $result;		
	}
}
